﻿/**	std_iterator.hpp
 *	----	Create Time Stamp	--2007-05-05 00:36:31--
 *------------------------------------------------------------------------------
 *	Mean	:
 *	Author	:Nick Shallery	(nicknide@gmail.com)
 *	Version	:1.0.3.3	(2008-01-07 22:16:28)
 *------------------------------------------------------------------------------
**/	/*YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.*/

#if			!defined(__LOLIX__TOY__STD_ITERATOR__NICK__K_IN_G__)
#define		__LOLIX__TOY__STD_ITERATOR__NICK__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------

#include	<iterator>

#if			!defined(__LOLIX__LOLI_X_CFG__K_IN_G__)
	#include	"../lolix_cfg.h"
#endif	//	!defined(__LOLIX__LOLI_X_CFG__K_IN_G__)

#if				!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
	#include	"../lolix_macro.h"
#endif	//	!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)

#if			LOLIX_CFG__IS_DEBUG
	#if			!defined(__LOLIX__TOY__L_X_ASSERT_NICK__K_IN_G__)
		#include	"./lx_assert.h"
	#endif	//	defined(__LOLIX__TOY__L_X_ASSERT_NICK__K_IN_G__)
#endif	//	LOLIX_CFG__IS_DEBUG

namespace lolix{namespace toy{
	namespace _help{
		template<typename _Itr, typename _TDif, typename _TCat>
			const _Itr _move_iterator(_Itr itr, _TDif dif, _TCat)
				{
				if ( dif > 0 )
					{
					for ( ; dif; --dif )
						++itr;
					}
				else if ( dif < 0 )
					{
					for ( ; dif; ++dif )
						--itr;
					}
				return itr;
				}
		template<typename _Itr, typename _TDif>
		const _Itr _move_iterator(_Itr itr, _TDif dif, std::random_access_iterator_tag)
				{
				return itr + dif;
				}
		}
	template<typename _Ty>
	class	value_iterator
		{
			typedef	value_iterator	this_type;
			_Ty*	_v;
			difference_type	_pos;
		public:
			typedef std::random_access_iterator_tag iterator_category;
			typedef _Ty								value_type;
			typedef difference_type					difference_type;
			typedef this_type						pointer;
			typedef _Ty&							reference;
			typedef const this_type					const_pointer;
			typedef const _Ty&						const_reference;

			value_iterator<_Ty>(void): _v(0), _pos(0){}
			template<typename Itr>
			value_iterator<_Ty>(Itr o, difference_type pos): _v(o), _pos(pos){}
			template<typename Itr>
			value_iterator<_Ty>(Itr o): _v(o), _pos(0){}

			LOLIX_INLINE_CALL	_Ty* operator->(void)const
				{
				return _v;
				}
			LOLIX_INLINE_CALL	reference operator*(void)const
				{
				return *_v;
				}
			LOLIX_INLINE_CALL	this_type& operator ++(void)
				{
				++_pos;
				return *this;
				}
			LOLIX_WARNING_FOR_PERFORMANCE("use prefix increment operator instead")
			LOLIX_INLINE_CALL	this_type& operator ++(int)
				{
				this_type tmp(*this);
				++*this;
				return tmp;
				}
			LOLIX_INLINE_CALL	this_type& operator --(void)
				{
				--_pos;
				return *this;
				}

			LOLIX_WARNING_FOR_PERFORMANCE("use prefix decrement operator instead")
			LOLIX_INLINE_CALL	this_type& operator --(int)
				{
				this_type tmp(*this);
				--*this;
				return tmp;
				}
			LOLIX_INLINE_CALL	this_type& operator +=(difference_type pos)
				{
				_pos += pos;
				return *this;
				}
			LOLIX_INLINE_CALL	this_type& operator -=(difference_type pos)
				{
				_pos -= pos;
				return *this;
				}
			LOLIX_INLINE_CALL	this_type operator +(difference_type pos)const
				{
				this_type tmp(*this);
				tmp += pos;
				return tmp;
				}
			LOLIX_INLINE_CALL	this_type operator -(difference_type pos)const
				{
				this_type tmp(*this);
				tmp -= pos;
				return tmp;
				}
			LOLIX_INLINE_CALL	const_reference operator[](difference_type)const
				{
				return *_v;
				}

			difference_type operator - (const this_type& o)const
				{
				LOLIX_ASSERT(_v == o._v, "lolix::toy::value_iterator::operator - (const this_type&o).");
				return _pos - o._pos;
				}

#undef		__LOLIX__TMP__DEFINE__LOGIC_CMP_FUNC
#define		__LOLIX__TMP__DEFINE__LOGIC_CMP_FUNC(__lx_v__)		\
			LOLIX_INLINE_CALL	bool operator __lx_v__ (const this_type& o)const{ LOLIX_ASSERT(_v == o._v, "wrong compera."); return _pos __lx_v__ o._pos;}
			__LOLIX__TMP__DEFINE__LOGIC_CMP_FUNC(<);
			__LOLIX__TMP__DEFINE__LOGIC_CMP_FUNC(<=);
			__LOLIX__TMP__DEFINE__LOGIC_CMP_FUNC(>);
			__LOLIX__TMP__DEFINE__LOGIC_CMP_FUNC(>=);
#undef		__LOLIX__TMP__DEFINE__LOGIC_CMP_FUNC
			LOLIX_INLINE_CALL	bool operator == (const this_type& o)const
				{
				return _v == o._v && _pos == o._pos;
				}
			LOLIX_INLINE_CALL	bool operator != (const this_type& o)const
				{
				return !((*this) == o);
				}

		};

	template<typename _Ty>
	value_iterator<_Ty> operator + ( typename value_iterator<_Ty>::difference_type pos, const value_iterator<_Ty> iter )
		{
		return iter + pos;
		}

	template<typename _Ty>
	value_iterator<_Ty> make_value_iterator(_Ty* ptr)
		{
		return value_iterator<_Ty>(ptr);
		}
	template<typename _Ty>
	value_iterator<_Ty> make_value_iterator(_Ty* ptr, typename value_iterator<_Ty>::difference_type pos)
		{
		return value_iterator<_Ty>(ptr, pos);
		}
	template<typename _Itr, typename _TDif>
	const _Itr	move_iterator(_Itr itr, _TDif dif)
		{
		return _help::_move_iterator(itr, dif, std::iterator_traits<_Itr>::iterator_category());
		}
}}

//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LOLIX__TOY__STD_ITERATOR__NICK__K_IN_G__)
